package com.lancoo.ccas53.arrangecourse.rulecheck;

import com.lancoo.ccas53.arrangecourse.entities.BaseRule;
import com.lancoo.ccas53.arrangecourse.entities.ClassHour;
import com.lancoo.ccas53.arrangecourse.entities.TeachingClassUnit;
import com.lancoo.ccas53.arrangecourse.entities.TimeslotRoom;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @Description 优先排排课，规则适配
 * @Author Fortysun
 * @Date 2023/8/24 10:45
 **/
@Slf4j
public class FixCourseRuleCheck extends RuleCheck implements RuleDecorator{
    //接收父类的规则服务对象
    private RuleService ruleService;

    public FixCourseRuleCheck(RuleService ruleService, BaseRule baseRule) {
        this.ruleService = ruleService;
        super.baseRule = baseRule;
    }

    /**
     * 检测优先排规则是否适合分配：
     * 判断待分配的教室课时分组，是否满足教学班设置的优先排规则
     * @param teachingClassUnit 教学班排课单元
     * @param continuousList 连上的教室课时分组信息列表
     * @param classHourMap 课表课时map
     * @return
     */
    @Override
    public Boolean isSuitable(TeachingClassUnit teachingClassUnit,
                  LinkedList<TimeslotRoom> continuousList,
                  ConcurrentHashMap<String, CopyOnWriteArrayList<ClassHour>> classHourMap) {
        //如果上一个增强的规则是符合要求的
        if (ruleService.isSuitable(teachingClassUnit, continuousList, classHourMap)) {
            //进行优先排规则的检测
            return isFixCourseSuitable(teachingClassUnit, continuousList);
        }

        return false;
    }


    /**
     * 尽量排分配的时候，判断是否符合尽量排设置的课时要求
     * @param teachingClassUnit 教学班排课单元信息；
     * @param continuousList 待分配的连续的教室课时分组信息
     * @return
     */
    private boolean isFixCourseSuitable(TeachingClassUnit teachingClassUnit,
                                        LinkedList<TimeslotRoom> continuousList) {
        //如果连上的教室课时分组列表信息为空，或者没有内容
        if (continuousList == null || continuousList.isEmpty()) {
//            log.error("#FixCourseRuleCheck.isFixCourseSuitable#:分配的教室课时分组信息列表为空~！！");
            return false;
        }
        //获取用户设置的尽量排规则，即尽量排的课时信息
        List<String> fixTimeslotCodeList = teachingClassUnit.getFixTimeslotCodes();

        if (fixTimeslotCodeList != null
                && !fixTimeslotCodeList.isEmpty()) {
            //将设置的优先排的课时列表，按照从小到大，进行排序
            Collections.sort(fixTimeslotCodeList);

            //将待分配的教室课时分组信息列表，按照课时编码，从小到大进行排序
            Collections.sort(continuousList, Comparator.comparing(TimeslotRoom::getTimeslotCode));

            //遍历用户设置的优先排的课时，如果待分配的教室课时列表中的第一个元素，
            // 匹配上了优先排中的某个课时，那么确定是符合优先排规则的
            //这个操作是为了更精确的尽量多的进行匹配。比如设置的优先排的课时有0101、0103、0105
            //如果这个教学班的连上节次是3，那么只要待分配的教室课时分组的课时编码是0101，
            //分配的三个连续的课时，必定是0101、0102、0103，这样在同一个半天内，就完美的覆盖了0101和0103
            for (String timeslotCode : fixTimeslotCodeList) {
                if (timeslotCode.equals(continuousList.get(0).getTimeslotCode())) {
                    return true;
                }
            }
            return false;
        }
        //未设置优先排的课时
        return true;
    }

}
